import {
  BaseCommand,
  CommandDialog,
  ICmdDialogParams,
  ICurve,
} from '@amcax/base';
import i18n from 'i18next';
import { useEffect, useRef, useState } from 'react';
import LineInteractor from '../cmd-line/CmdInteractor';
import TangencyArcInteractor from '../cmd-tangency-arc/tangency-arc';
import ThreePointArcInteractor from '../cmd-arc/three-point-arc';
import { Radio } from 'antd';
import { CommandFormWrapper } from '@app-base/common/components/command-form';
import { useCommand } from '@app-base/common/hooks/useCommand';
import { LOADING_EVENTS } from '@app-base/common/Constants';
import { userEvents } from '@app-base/module';

function OutlineCommand({ title, onClose }: ICmdDialogParams) {
  const cmdRef = useRef<
    LineInteractor | TangencyArcInteractor | ThreePointArcInteractor
  >(null);

  const [actionType, setActionType] = useState<
    'line' | 'tangencyArc' | 'threePointArc'
  >('line');

  const lastPoint = useRef<string>();
  const [lastCurve, setLastCurve] = useState<ICurve>();
  const [isLoading, setIsLoading] = useState(false);

  useCommand('cmd-outline', {
    onClose,
  });

  useEffect(() => {
    userEvents.on(LOADING_EVENTS.LOADING_CHANGE, setIsLoading);

    return () => {
      userEvents.off(LOADING_EVENTS.LOADING_CHANGE, setIsLoading);
    };
  }, []);

  useEffect(() => {
    if (actionType === 'line') {
      const newInteractor = new LineInteractor(
        '2point',
        (c) => {
          lastPoint.current = c.relative[1];
          setLastCurve(c);
        },
        false,
      );

      if (lastPoint.current) {
        newInteractor.setStartPoint(lastPoint.current);
      }

      cmdRef.current = newInteractor;
    } else if (actionType === 'tangencyArc') {
      const newInteractor = new TangencyArcInteractor(
        (c) => {
          lastPoint.current = c.relative[2];
          setLastCurve(c);
          setActionType('line');
        },
        true,
        false,
      );

      if (lastPoint.current) {
        newInteractor.setStartPoint(lastPoint.current, lastCurve);
      }
      cmdRef.current = newInteractor;
    } else {
      const newInteractor = new ThreePointArcInteractor(
        (c, p) => {
          lastPoint.current = p;
          setLastCurve(c);
          setActionType('line');
        },
        true,
        false,
      );

      if (lastPoint.current) {
        newInteractor.setStartPoint(lastPoint.current);
      }
      cmdRef.current = newInteractor;
    }
    return () => {
      cmdRef.current?.destroy();
      cmdRef.current = null;
    };
  }, [actionType]);
  return (
    <CommandDialog
      title={title}
      onClose={onClose}
      placement='topLeft'
    >
      <CommandFormWrapper>
        <Radio.Group
          disabled={isLoading}
          value={actionType}
          onChange={(e) => setActionType(e.target.value)}
          options={[
            { value: 'line', label: '直线' },
            {
              value: 'tangencyArc',
              label: '相切圆弧',
              disabled: lastCurve == null,
            },
            { value: 'threePointArc', label: '三点圆弧' },
          ]}
        />
      </CommandFormWrapper>
    </CommandDialog>
  );
}

export const cmdSketchOutline: BaseCommand = {
  id: 'CmdSketchOutline',
  label: 'command.sketch-cmds.outline',
  icon: 'commands/sketch/outline',
  group: 'sketch',
  create: function (label: string, onClose: () => void) {
    return (
      <OutlineCommand
        title={i18n.t(label)}
        onClose={onClose}
      />
    );
  },
};
